package com.zhouyu.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.nio.charset.Charset;
import java.util.Arrays;

/**
 * @ClassName: PKCS7Crypto
 * @author zhongjyuan
 * @date 2020年7月23日 上午10:10:27
 * @Description: TODO: PKCS7算法加解密工具
 * 
 */
@Component
public class PKCS7Crypto {
	private static Logger log = LoggerFactory.getLogger(PKCS7Crypto.class);
	/**
	 * @author zhongjyuan
	 * @data 2020年7月23日上午10:10:51
	 * @Fields BLOCK_SIZE : TODO: 补位数
	 */
	static int BLOCK_SIZE = 32;
	/**
	 * @author zhongjyuan
	 * @data 2020年7月23日上午10:11:00
	 * @Fields CHARSET : TODO: 编码规则
	 */
	static Charset CHARSET = Charset.forName("utf-8");

	/**
	 * @Title: encode @Author zhongjyuan @Data 2020年7月23日上午10:11:10 @Description:
	 * TODO(对明文进行补位填充的字节) @param @param count 补位数 @param @return 参数说明 @return byte[]
	 * 返回类型 @throws
	 */
	public static byte[] encode(int count) {
		log.trace("======PKCS7Crypto======encode()======begin======");

		// 计算需要填充的位数
		int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
		if (amountToPad == 0) {
			amountToPad = BLOCK_SIZE;
		}

		// 获得补位所用的字符
		char padChr = chr(amountToPad);
		String tmp = new String();
		for (int index = 0; index < amountToPad; index++) {
			tmp += padChr;
		}

		return tmp.getBytes(CHARSET);
	}

	/**
	 * @Title: decode @Author zhongjyuan @Data 2020年7月23日上午10:11:43 @Description:
	 * TODO(删除解密后明文的补位字符) @param @param decrypted 解密后的明文 @param @return 参数说明 @return
	 * byte[] 返回类型 @throws
	 */
	public static byte[] decode(byte[] decrypted) {
		log.trace("======PKCS7Crypto======decode()======begin======");

		int pad = (int) decrypted[decrypted.length - 1];
		if (pad < 1 || pad > 32) {
			pad = 0;
		}

		return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
	}

	/**
	 * @Title: chr @Author zhongjyuan @Data 2020年7月23日上午10:12:18 @Description:
	 * TODO(将数字转化成ASCII码对应的字符，用于对明文进行补码) @param @param number 需要转化的数字 @param @return
	 * 参数说明 @return char 返回类型 @throws
	 */
	public static char chr(int number) {
		byte target = (byte) (number & 0xFF);
		return (char) target;
	}
}
